<template>
  <div>
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="42%" :close-on-click-modal="false" append-to-body>

      <template v-if="fileType === 'image'">
        <div v-loading="tableLoading" class="upload-list-wrap">
          <div v-for="(item,i) in items" :key="i" class="img-box-wrap">
            <i class="i-remove el-icon-circle-close" :title="'删除'" @click="deleteAttachment(item.id)"></i>
            <i class="i-view el-icon-view" :title="'查看'" @click="imageViewModalShow(item.url)"></i>
            <!-- 请求时，因为返回的url是string类型，所以一律返回原图链接，在本modal中处理展示尺寸  -->
            <!-- 在该modal中的图片列表中，图片展示的尺寸。与选择返回的尺寸无关  需配置对应的服务商的图片样式  -->
            <el-image style="width: 120px; height: 120px" :src="item.url | imageStyle('zoom.120.120','-')" :alt="item.friendlyFileName" :title="item.friendlyFileName"></el-image>
            <el-checkbox v-model="item.isActive" class="i-checkbox" :title="item.friendlyFileName" @change="checkboxChange(item)">{{ item.friendlyFileName }}</el-checkbox>
          </div>
        </div>
      </template>

      <template v-else-if="fileType === 'video'">
        <div v-loading="tableLoading" class="upload-list-wrap">
          <div v-for="(item,i) in items" :key="i" class="img-box-wrap">
            <i class="i-remove el-icon-circle-close" :title="'删除'" @click="deleteAttachment(item.id)"></i>
            <video :src="item.url" controls="controls" width="120px" height="120px">
              您的浏览器不支持 video 标签。
            </video>
            <el-checkbox v-model="item.isActive" class="i-checkbox" :title="item.friendlyFileName" @change="checkboxChange(item)">{{ item.friendlyFileName }}</el-checkbox>
          </div>
        </div>
      </template>

      <template v-else>
        <div v-loading="tableLoading" class="upload-list-wrap">
          <div v-for="(item,i) in items" :key="i">
            <el-checkbox v-model="item.isActive" class="i-checkbox" :title="item.friendlyFileName" @change="checkboxChange(item)">{{ item.friendlyFileName }}</el-checkbox>
            <i class="i-remove el-icon-circle-close" :title="'删除'" @click="deleteAttachment(item.id)"></i>
          </div>
        </div>
      </template>

      <pagination v-show="totalCount > 0" :layout="layout" :total="totalCount" :skip-count.sync="q.offset" :max-result-count.sync="q.limit" @pagination="getList" />

      <div slot="footer" class="dialog-footer">
        <el-upload ref="upload" :action="action" :headers="headers" multiple :data="data" auto-upload :before-upload="beforeUpload" :on-progress="onProgress" :on-success="onSuceess" :on-error="onError" :on-change="onUploadChange" :show-file-list="false" style="float:left;">
          <el-button slot="trigger" type="primary" :loading="isUploading">上传</el-button> <span>{{ uploadingTip }}</span>
        </el-upload>
        <el-button @click="close()">取消</el-button>
        <el-button type="primary" @click="save()">确认选择</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getMyAttachmentPagedList, deleteAttachment } from "@/api/business/attachment";
import Pagination from "@/components/ApePagination";
import { getToken } from "@/utils/auth/token";

export default {
  name: "ApeFileDialog",
  components: { Pagination },
  props: {
    // ['image', 'audio', 'video', 'file', 'other']
    fileType: {
      type: String,
      default: 'image'
    },
    multiple: {
      type: Boolean,
      default: false
    },
    allowedExtension: {
      type: Array,
      default: () => {
        return [];
      }
    },
    fileMaxSize: {
      type: Number,
      default: 10
    }
  },
  data() {
    return {
      dialogVisible: false,
      q: {
        keywords: undefined,
        file_type: this.fileType,
        offset: 0,
        limit: 10
      },
      totalCount: 0,
      items: [],
      itemsChecked: [],
      tableLoading: true,
      tableKey: 0,

      isUploading: false,
      uploadingTip: '',
      layout: 'total, prev, pager, next, jumper',

      data: {
        file_type: this.fileType,
        file_id: '',
        file_name: ''
      },
      action: process.env.VUE_APP_BASE_API + "/api/business/files/upload/"
    };
  },
  computed: {
    headers() {
      var headers = {};
      headers["Authorization"] = "Bearer " + getToken();
      return headers;
    },
    dialogTitle() {
      var result = "选择文件";
      switch (this.fileType) {
        case 'image':
          result = "选择图片";
          break;
        case 'audio':
          result = "选择音频";
          break;
        case 'video':
          result = "选择视频";
          break;
        default:
          result = "选择文件";
          break;
      }
      return result;
    }
  },
  methods: {
    // 打开选择图片和上传图片的Dialog
    open() {
      this.dialogVisible = true;
      this.uploadingTip = '';

      this.load();
    },
    // 加载我的图片列表
    load() {
      this.q.offset = 0;
      this.getList();
    },
    // 加载我的图片列表
    getList() {
      this.tableLoading = true;
      getMyAttachmentPagedList(this.q).then(result => {
        result.items.forEach(element => {
          element.isActive = false;
        });

        this.items = [...result.items];
        this.totalCount = result.total_count;
        this.tableLoading = false;
      });
    },
    checkboxChange(item) {
      if (!this.multiple) {
        this.items.forEach(element => {
          if (item.id !== element.id) {
            element.isActive = false;
          }
        });
      }
    },
    // 将选择的图片返回
    save() {
      const selectedItems = this.items.filter(n => n.isActive) || [];
      if (selectedItems.length < 1) {
        this.$message.warning("请至少选择一个文件");
        return;
      } else {
        var result = selectedItems.map(m => {
          const item = {};
          item.file_id = m.id;
          item.url = m.url;
          item.friendly_file_name = m.friendly_file_name;
          return item;
        });
        if (this.multiple) {
          this.$emit("save", result);
        } else {
          this.$emit("save", result[0]);
        }
        this.dialogVisible = false;
      }
    },
    // 删除我的图片附件
    deleteAttachment(id) {
      this.$confirm("删除后不可恢复，并且删除该文件的所有关联关系。?", "确定删除该文件吗？", { type: "warning" })
        .then(() => {
          deleteAttachment(id).then(() => {
            this.load();
            this.$message({ message: "删除成功", type: "success" });
          });
        })
        .catch(() => { });
    },
    // 关闭Dialog
    close() {
      this.dialogVisible = false;
      this.isUploading = false; // 无论成功失败，都把按钮的loading状态取消
    },
    // 上传文件之前的钩子，参数为上传的文件，若返回 false 或者返回 Promise 且被 reject，则停止上传。
    beforeUpload(file) {
      const fileName = file.name;
      const fileSize = file.size;
      if (this.allowedExtension && this.allowedExtension.length > 0) {
        if (this.allowedExtension.filter(item => fileName.indexOf(`.${item}`) > -1).length <= 0) {
          this.$message.error(`只允许上传${this.allowedExtension.join(",")}文件`);
          return false;
        }
      }
      if (fileSize > this.fileMaxSize * 1024 * 1024) {
        this.$message.error(`文件大小不能超过 ${this.fileMaxSize}MB!`);
        return false;
      }
      this.data.fileNames = [fileName];
      return true;
    },
    onProgress(event, file, fileList) {
      var percent = event.percent;
      if (event.percent === 100) {
        percent = 99.99;
      }
      this.uploadingTip = `${percent.toFixed(2)}%`;
    },
    // 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
    onUploadChange(file, fileList) {
    },
    // 文件上传成功时的钩子
    onSuceess(response, file, fileList) {
      if (response && response.success) {
        this.$message({ message: "上传成功", type: "success" });
        this.load();
      } else {
        var message = (response && response.message) || "上传出错，请重新上传";
        this.$message({ message: message, type: "error" });
      }
      this.isUploading = false;
      this.uploadingTip = ``;
    },
    // 文件上传失败时的钩子
    onError(err, file, fileList) {
      if (err) {
        this.$message({ message: '上传失败，请稍后再试', type: "error" });
        this.isUploading = false;
        this.uploadingTip = ``;
      }
    }
  }
};
</script>

<style lang="scss">
.upload-list-wrap {
  overflow: hidden;
  .img-box-wrap {
    float: left;
    position: relative;
    width: 120px;
    height: 120px;
    margin: 6px;
    img {
      position: relative;
      width: 100%;
      height: 100%;
    }
    i {
      position: absolute;
      top: 10px;
      right: 10px;
      z-index: 1;
      width: 25px;
      height: 25px;
      text-align: center;
      line-height: 25px;
      display: none;
      cursor: pointer;
      font-size: 20px;
    }
    .i-remove {
      top: -10px;
      right: -12px;
      color: #f00;
      z-index: 2;
    }
    .i-view {
      top: 0;
      right: 0;
      width: 100%;
      left: 0;
      height: 120px;
      line-height: 120px;
      background: rgba(51, 51, 51, 0.3);
      color: #fff;
      text-align: center;
    }
    &:hover {
      i {
        display: block;
      }
    }
    label {
      position: absolute;
      bottom: 0;
      padding: 2px 5px 3px;
      line-height: normal;
      right: 0;
      left: 0;
      z-index: 1;
      background-color: #333333;
      color: #ffffff;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}
</style>
